package com.sxit.tdf.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sxit.tdf.server.entity.FileBucket;
import com.sxit.tdf.server.entity.FilePath;
import com.sxit.tdf.server.entity.bo.SimpleFilePathInfoBo;
import com.sxit.tdf.server.entity.vo.InsertFileFolderVo;
import com.sxit.tdf.server.exception.TdfException;
import com.sxit.tdf.server.mapper.FilePathMapper;
import com.sxit.tdf.server.service.IFileBucketService;
import com.sxit.tdf.server.service.IFilePathService;
import com.sxit.tdf.server.util.OSSUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 服务实现类
 *
 * @author 橙子高
 * @since 2022-02-23
 */
@Service
public class FilePathServiceImpl extends ServiceImpl<FilePathMapper, FilePath>
    implements IFilePathService {

  @Autowired IFileBucketService fileBucketService;

  @Override
  public FilePath findFileByPathCode(String pathCode) {
    return baseMapper.findFileByPathCode(pathCode);
  }

  @Override
  @Transactional
  public Boolean createFileFolder(InsertFileFolderVo insertFileFolderVo) {

    // 获取筒
    FileBucket bucket = fileBucketService.getById(insertFileFolderVo.getBucketId());
    // 获取父级信息信息
    FilePath parent = baseMapper.selectById(insertFileFolderVo.getParent());

    String pathCode = "";

    if (insertFileFolderVo.getParent() == 0) {
      pathCode = insertFileFolderVo.getPathCode();
    } else {
      pathCode = parent.getPathCode() + insertFileFolderVo.getPathCode();
    }

    Boolean isCanInsertFolder = baseMapper.canInsertFolder(insertFileFolderVo.getPathName());
    if (isCanInsertFolder) {
      throw new TdfException("该文件夹已存在");
    }

    // 插入新的文件信息
    FilePath filePath = new FilePath();
    filePath.setPathName(insertFileFolderVo.getPathName());
    filePath.setCreateTime(LocalDateTime.now());
    filePath.setParent(insertFileFolderVo.getParent());
    filePath.setPathCode(pathCode);

    filePath.setBucketId(insertFileFolderVo.getBucketId());
    filePath.setChildren("[]");
    baseMapper.insert(filePath);
    // 修改父级文件
    if (insertFileFolderVo.getParent() != 0) {
      String children = parent.getChildren();
      List<Integer> integers = JSONArray.parseArray(children, Integer.class);
      integers.add(filePath.getId());
      parent.setChildren(JSON.toJSONString(integers));
      baseMapper.updateById(parent);
      // 创建新的文件
      OSSUtil ossUtil = new OSSUtil();
      ossUtil.createFolder(
          bucket.getBucketCode(), parent.getPathCode() + insertFileFolderVo.getPathCode());
    } else {
      // 创建新的文件
      OSSUtil ossUtil = new OSSUtil();
      ossUtil.createFolder(bucket.getBucketCode(), insertFileFolderVo.getPathCode());
    }

    return null;
  }

  @Override
  @Transactional
  public Boolean deleteFileFolder(Integer id) {

    Boolean canDelete = baseMapper.canDeleteFolder(id);
    Boolean canDeleteFile = baseMapper.canDeleteFolderFile(id);
    // 判断是否能够删除
    if (canDelete && canDeleteFile) {
      FilePath filePath = baseMapper.selectById(id);

      // 删除文件夹
      if (filePath != null) {
        // 如果为0 则为父节点 直接删除 否则需要修改父节点数据
        if (filePath.getParent() == 0) {
          FileBucket bucket = fileBucketService.getById(filePath.getBucketId());
          baseMapper.deleteById(id);
          new OSSUtil().deleteFolder(bucket.getBucketCode(), filePath.getPathCode());
        } else {
          // 明天写 查找父节点 然后修改父节点的子节点数据
          FilePath parent = baseMapper.selectById(filePath.getParent());
          String children = parent.getChildren();
          List<Integer> integers = JSONArray.parseArray(children, Integer.class);
          integers.remove(id);
          parent.setChildren(JSON.toJSONString(integers));
          baseMapper.updateById(parent);

          FileBucket bucket = fileBucketService.getById(filePath.getBucketId());
          baseMapper.deleteById(id);
          new OSSUtil().deleteFolder(bucket.getBucketCode(), filePath.getPathCode());
        }
      }

    } else {
      throw new TdfException("该文件夹下仍有文件夹，请删除又再操作");
    }

    return false;
  }

  @Override
  public HashMap<String, List<SimpleFilePathInfoBo>> getFolderList() {

    List<SimpleFilePathInfoBo> filePaths = baseMapper.selectPathInfoList();
    HashMap<Integer, SimpleFilePathInfoBo> map = new HashMap();

    filePaths.forEach(
        item -> {
          map.put(item.getId(), item);
        });

    HashMap<String, List<SimpleFilePathInfoBo>> result = new HashMap<>();

    filePaths.forEach(
        item -> {
          if (item.getParent() == 0) {
            List<SimpleFilePathInfoBo> children = getChildren(map, item);

            if (result.containsKey(item.getBucketName())) {

              List<SimpleFilePathInfoBo> temp = result.get(item.getBucketName());

              item.setChildrenList(children);

              temp.add(item);
              result.put(item.getBucketName(), temp);
            } else {
              ArrayList<SimpleFilePathInfoBo> temp = new ArrayList<>();
              item.setChildrenList(children);
              temp.add(item);
              result.put(item.getBucketName(), temp);
            }
          }
        });

    return result;
  }

  @Override
  public HashMap<String, List<SimpleFilePathInfoBo>> getFolderListByBucketId(Integer id) {

    List<SimpleFilePathInfoBo> filePaths = baseMapper.selectPathInfoListByBucketId(id);
    HashMap<Integer, SimpleFilePathInfoBo> map = new HashMap();

    filePaths.forEach(
        item -> {
          map.put(item.getId(), item);
        });

    HashMap<String, List<SimpleFilePathInfoBo>> result = new HashMap<>();

    filePaths.forEach(
        item -> {
          if (item.getParent() == 0) {
            List<SimpleFilePathInfoBo> children = getChildren(map, item);

            if (result.containsKey(item.getBucketName())) {

              List<SimpleFilePathInfoBo> temp = result.get(item.getBucketName());

              item.setChildrenList(children);

              temp.add(item);
              result.put(item.getBucketName(), temp);
            } else {
              ArrayList<SimpleFilePathInfoBo> temp = new ArrayList<>();
              item.setChildrenList(children);
              temp.add(item);
              result.put(item.getBucketName(), temp);
            }
          }
        });

    return result;
  }

  private List<SimpleFilePathInfoBo> getChildren(
      HashMap<Integer, SimpleFilePathInfoBo> map, SimpleFilePathInfoBo content) {
    List<Integer> ids = JSONArray.parseArray(content.getChildren(), Integer.class);
    if (ids.size() == 0) {
      return null;
    }
    ArrayList<SimpleFilePathInfoBo> result = new ArrayList<>();
    ids.forEach(
        item -> {
          SimpleFilePathInfoBo data = map.get(item);
          data.setChildrenList(getChildren(map, data));
          result.add(data);
        });

    return result;
  }
}
